package com.demo.practiceui.views.interactive;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 拖拽排序控件
 * 核心知识点：
 * 1. 自定义ViewGroup - 管理子View布局
 * 2. onInterceptTouchEvent - 拦截触摸事件
 * 3. 拖拽逻辑 - 位置交换
 * 4. 动画 - 平滑移动效果
 */
public class DragSortView extends View {

    // 数据项
    private static class Item {
        String text;
        float x;
        float y;
        float targetX;
        float targetY;
        int originalIndex;

        Item(String text, int index) {
            this.text = text;
            this.originalIndex = index;
        }
    }

    // 数据列表
    private List<Item> items = new ArrayList<>();
    private String[] defaultItems = {"任务 1", "任务 2", "任务 3", "任务 4", "任务 5", "任务 6", "任务 7","renn","task 8"};

    // 画笔
    private Paint itemPaint;
    private Paint textPaint;
    private Paint dragPaint;

    // 尺寸
    private int width;
    private int height;
    private float itemWidth = 0;
    private float itemHeight = 100f;
    private float itemSpacing = 20f;
    private int columns = 3;

    // 拖拽相关
    private int dragIndex = -1;
    private float dragOffsetX;
    private float dragOffsetY;
    private float touchDownX;
    private float touchDownY;

    public DragSortView(Context context) {
        this(context, null);
    }

    public DragSortView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DragSortView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        // 普通项画笔
        itemPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        itemPaint.setColor(Color.parseColor("#E3F2FD"));
        itemPaint.setStyle(Paint.Style.FILL);

        // 拖拽项画笔
        dragPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        dragPaint.setColor(Color.parseColor("#2196F3"));
        dragPaint.setStyle(Paint.Style.FILL);
        dragPaint.setShadowLayer(15, 0, 5, Color.parseColor("#80000000"));

        // 文字画笔
        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setColor(Color.parseColor("#333333"));
        textPaint.setTextSize(36f);
        textPaint.setTextAlign(Paint.Align.CENTER);

        setLayerType(LAYER_TYPE_SOFTWARE, null);

        // 初始化数据
        for (int i = 0; i < defaultItems.length; i++) {
            items.add(new Item(defaultItems[i], i));
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        if (widthMode == MeasureSpec.AT_MOST) {
            width = 600;
        }
        if (heightMode == MeasureSpec.AT_MOST) {
            int rows = (int) Math.ceil((double) items.size() / columns);
            height = (int) (rows * (itemHeight + itemSpacing) + itemSpacing);
        }
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
        itemWidth = (width - (columns + 1) * itemSpacing) / columns;

        // 布局所有项
        layoutItems();
    }

    /**
     * 布局所有项
     */
    private void layoutItems() {
        for (int i = 0; i < items.size(); i++) {
            Item item = items.get(i);
            int row = i / columns;
            int col = i % columns;

            item.targetX = itemSpacing + col * (itemWidth + itemSpacing);
            item.targetY = itemSpacing + row * (itemHeight + itemSpacing);

            // 如果还没有初始位置，直接设置
            if (item.x == 0 && item.y == 0) {
                item.x = item.targetX;
                item.y = item.targetY;
            }
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        for (int i = 0; i < items.size(); i++) {
            Item item = items.get(i);

            // 跳过正在拖拽的项（最后绘制）
            if (i == dragIndex) {
                continue;
            }

            drawItem(canvas, item, false);
        }

        // 最后绘制拖拽项（在最上层）
        if (dragIndex >= 0 && dragIndex < items.size()) {
            drawItem(canvas, items.get(dragIndex), true);
        }
    }

    /**
     * 绘制单个项
     */
    private void drawItem(Canvas canvas, Item item, boolean isDragging) {
        Paint paint = isDragging ? dragPaint : itemPaint;

        // 绘制背景
        RectF rect = new RectF(item.x, item.y, item.x + itemWidth, item.y + itemHeight);
        canvas.drawRoundRect(rect, 15, 15, paint);

        // 绘制文字
        textPaint.setColor(isDragging ? Color.WHITE : Color.parseColor("#333333"));
        float textX = item.x + itemWidth / 2;
        float textY = item.y + itemHeight / 2 + 12;
        canvas.drawText(item.text, textX, textY, textPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            //防止父容器拦截触摸事件
            if (getParent() != null) {
                getParent().requestDisallowInterceptTouchEvent(true);
            }
                touchDownX = event.getX();
                touchDownY = event.getY();

                // 查找触摸的项
                dragIndex = findItemAtPosition(touchDownX, touchDownY);
                if (dragIndex >= 0) {
                    Item item = items.get(dragIndex);
                    dragOffsetX = touchDownX - item.x;
                    dragOffsetY = touchDownY - item.y;
                    return true;
                }
                break;

            case MotionEvent.ACTION_MOVE:
                //防止父容器拦截触摸事件
                if (getParent() != null) {
                    getParent().requestDisallowInterceptTouchEvent(true);
                }
                if (dragIndex >= 0) {
                    Item dragItem = items.get(dragIndex);
                    dragItem.x = event.getX() - dragOffsetX;
                    dragItem.y = event.getY() - dragOffsetY;

                    // 检查是否需要交换位置
                    checkForSwap(dragItem);

                    invalidate();
                    return true;
                }
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                //防止父容器拦截触摸事件
                if (getParent() != null) {
                    getParent().requestDisallowInterceptTouchEvent(false);
                }
                if (dragIndex >= 0) {
                    // 动画回到目标位置
                    animateItemToTarget(items.get(dragIndex));
                    dragIndex = -1;
                    invalidate();
                    return true;
                }
                break;
        }

        return super.onTouchEvent(event);
    }

    /**
     * 查找指定位置的项
     */
    private int findItemAtPosition(float x, float y) {
        for (int i = 0; i < items.size(); i++) {
            Item item = items.get(i);
            if (x >= item.x && x <= item.x + itemWidth &&
                    y >= item.y && y <= item.y + itemHeight) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 检查是否需要交换位置
     */
    private void checkForSwap(Item dragItem) {
        float dragCenterX = dragItem.x + itemWidth / 2;
        float dragCenterY = dragItem.y + itemHeight / 2;

        for (int i = 0; i < items.size(); i++) {
            if (i == dragIndex) {
                continue;
            }

            Item item = items.get(i);
           // float centerX = item.x + itemWidth / 2;
          //  float centerY = item.y + itemHeight / 2;

            // 判断拖拽项中心是否在其他项范围内
            if (dragCenterX >= item.x && dragCenterX <= item.x + itemWidth &&
                    dragCenterY >= item.y && dragCenterY <= item.y + itemHeight) {

                // 交换列表中的位置
                Collections.swap(items, dragIndex, i);

                // 重新布局
                layoutItems();

                // 动画移动其他项
                animateItemToTarget(item);

                // 更新拖拽索引
                dragIndex = i;

                break;
            }
        }
    }

    /**
     * 动画移动项到目标位置
     */
    private void animateItemToTarget(Item item) {
        ValueAnimator animatorX = ValueAnimator.ofFloat(item.x, item.targetX);
        ValueAnimator animatorY = ValueAnimator.ofFloat(item.y, item.targetY);

        animatorX.setDuration(200);
        animatorY.setDuration(200);

        animatorX.addUpdateListener(animation -> {
            item.x = (float) animation.getAnimatedValue();
            invalidate();
        });

        animatorY.addUpdateListener(animation -> {
            item.y = (float) animation.getAnimatedValue();
            invalidate();
        });

        animatorX.start();
        animatorY.start();
    }

    /**
     * 设置数据
     */
    public void setItems(String[] items) {
        this.items.clear();
        for (int i = 0; i < items.length; i++) {
            this.items.add(new Item(items[i], i));
        }
        requestLayout();
        invalidate();
    }

    /**
     * 获取当前排序
     */
    public List<String> getCurrentOrder() {
        List<String> order = new ArrayList<>();
        for (Item item : items) {
            order.add(item.text);
        }
        return order;
    }
    //增加项
    public void addItem(String item) {
        items.add(new Item(item, items.size()));
        requestLayout();
        invalidate();
    }
    //删除项
    public void removeItem(int index) {
        items.remove(index);
        requestLayout();
        invalidate();
    }
}

